home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / ril.zip / ril.c < prev    next >
C/C++ Source or Header  |  1992-09-08  |  14KB  |  602 lines

  1. /*                               -*- Mode: C -*- 
  2.  * ril.c
  3.  * 
  4.  * Description     : Roger's Interface Language
  5.  *         This file implements a TCL front end for processing "RIL" files.
  6.  *         An RIL file is a file of "RIL code" which can be translated into
  7.  *         X resource specifications.  These resource specs are then merged
  8.  *         into the current X resource data base.
  9.  * 
  10.  * Author          : Roger Reynolds
  11.  * Created On      : Wed Mar 18 12:34:20 1992
  12.  * 
  13.  * Configuration Management
  14.  * 
  15.  * @(#)ril.c    1.3    6/30/92
  16.  * 
  17.  * VERSION   SPR   MODIFIER   DATE AND TIME
  18.  * 1.7       0     rogerr     Mon Aug 31 12:23:17 1992
  19.  *           pass PROJECTROOT define through to ril so it can know where 
  20.  *           to look for app-defaults directory 
  21.  * 1.6       0     rogerr     Mon Aug 31 11:49:44 1992
  22.  *           use XtNewString for strsave look for files in 
  23.  *           /usr/X11R5/lib/.... now 
  24.  * 1.5       0     rogerr     Tue Jul 28 14:12:11 1992
  25.  *           fix bug pointed out by use of acc, whereby I was 
  26.  *           re-allocating widgetBuf for every input line read! 
  27.  * 1.4       0     rogerr     Tue Jul 14 16:42:56 1992
  28.  *           separate paths for Widget and Resource commands, though 
  29.  *           they ultimately end up in the same place, for now. 
  30.  * 1.3       0     rogerr     Tue Jun 30 13:17:55 1992
  31.  *           set rilXVersion before loading file so a script can tell if 
  32.  *           it is 11.5 or 11.4 
  33.  * 1.2       0     rogerr     Fri Jun 26 16:13:53 1992
  34.  *           added rilInterInit 
  35.  * 
  36.  */
  37.  
  38. #include <stdio.h>
  39. #include <errno.h>
  40.  
  41. #include <ril.h>
  42.  
  43. static char *ProgramName;
  44. char *rilResolvePathName();
  45.  
  46. /* Widget command resources - a long string */
  47. static    char *widgetBuf;
  48. static int widgetBufLen, widgetBufAllocCnt;
  49.  
  50. /* Resource command resources - a list of strings */
  51. static    char **resbuf;
  52. static int resbufLen, resbufAllocCnt;
  53.  
  54. static char res[4096];
  55. static char buf[4096];
  56.  
  57. #define MAX_PARENT_LEVEL 10
  58. static char *rilParentStrings[MAX_PARENT_LEVEL+1];
  59. static char rilParentVar[256];
  60. static int rilParent;
  61.  
  62. #ifdef DEBUG_ON
  63. #define DEBUG(stmt) { stmt }    
  64. #else
  65. #define DEBUG(stmt)
  66. #endif
  67.  
  68. static int
  69. _widgetCmd(clientData, interp, argc, argv, flag)
  70.     ClientData clientData;
  71.     Tcl_Interp *interp;
  72.     int argc;
  73.     char *argv[];
  74.     Boolean flag;        /* TRUE - place in list for fallback resources */
  75. {
  76.     int i, len;
  77.     char *name = argv[1];
  78.     char *p1, *p2, *p3, *p4;
  79.  
  80.     if (flag)
  81.     {
  82.         if (resbufAllocCnt == 0)
  83.         {
  84.             resbuf = (char**)XtCalloc((resbufAllocCnt=1000), sizeof(char*));
  85.         }
  86.     }
  87.     else
  88.     {
  89.         if (widgetBufAllocCnt == 0)
  90.         {
  91.             widgetBuf = (char*)XtMalloc(widgetBufAllocCnt=1000);
  92.             sprintf (widgetBuf, "\n");
  93.         }
  94.     }
  95.  
  96.     for (i=2; i < argc; i++)
  97.     {
  98.         DEBUG (fprintf (stderr, "args[%d] = <%s>", i, argv[i]););
  99.  
  100.         sprintf (buf, "%s\n", argv[i]);
  101.         for (p1=buf; *p1 && isspace(*p1); p1++)
  102.             if (! *p1) break;
  103.         while ((p2 = (char*)strchr(p1, '\n')) != NULL)
  104.         {
  105.             if (*(p2-1) == '\\')
  106.             {
  107.                 *(p2-1) = ' ';
  108.                 continue;
  109.             }
  110.  
  111.             *p2 = NULL;
  112.             if (rilParent > 0)
  113.             {
  114.                 sprintf (res, "%s%s.", rilParentVar, name);
  115.             }
  116.             else
  117.                 sprintf (res, "%s.", name);
  118.  
  119.             p4 = res + strlen(res);
  120.             for (p3=p1; p3 <= p2; p3++)
  121.             {
  122.                 if (*p3 == '$' && *(p3-1) != '\\')
  123.                 {
  124.                     char *var, *val, saved;
  125.                     for (var= ++p3; 
  126.                          *p3 && 
  127.                          ((*p3 >= '0' && *p3 <= '9') ||
  128.                           (*p3 >= 'A' && *p3 <= 'Z') ||
  129.                           (*p3 >= 'a' && *p3 <= 'z') ||
  130.                           (*p3 == '_'));
  131.                          p3++)
  132.                         ;
  133.                     saved = *p3;
  134.                     *p3 = NULL;
  135.                     val = Tcl_GetVar(interp, var, NULL);
  136.                     DEBUG (fprintf (stderr, "var <%s> val=<%s>\n", var, val););
  137.                     for (; val && *val; val++)
  138.                         *p4++ = *val;
  139.                     *p4++ = saved;
  140.                     *p4 = NULL;
  141.                 }
  142.                 else
  143.                 {
  144.                     *p4++ = *p3;
  145.                     *p4 = NULL;
  146.                 }
  147.             }
  148.  
  149.             len = strlen(res);
  150.             DEBUG (fprintf (stderr, "<%s> len=%d\n", res, len););
  151.  
  152.             if (flag)
  153.             {
  154.                 if (resbufLen >= resbufAllocCnt)
  155.                 {
  156.                     resbufAllocCnt+=100;
  157.                     resbuf = (char**)
  158.                         XtRealloc(resbuf, (sizeof(char*)*(resbufAllocCnt)));
  159.                 }
  160.             }
  161.             else
  162.             {
  163.                 if ((widgetBufLen + len + 1) >= widgetBufAllocCnt)
  164.                 {
  165.                     widgetBufAllocCnt += len + 1000;
  166.                     widgetBuf = (char*)
  167.                         XtRealloc(widgetBuf, (widgetBufAllocCnt));
  168.                 }
  169.             }
  170.  
  171.             /* chop off trailing spaces in resource spec */
  172.             for (p3=p4-2; isspace(*p3); p3--) 
  173.                 *p3 = NULL;
  174.  
  175.             if (flag)
  176.             {
  177.                 resbuf[resbufLen++] = XtNewString(res);
  178.             }
  179.             else
  180.             {
  181.                 strcat (widgetBuf, res);
  182.                 strcat (widgetBuf, "\n");
  183.                 widgetBufLen += len + 1;
  184.             }
  185.  
  186.             for (p1= ++p2; *p1 && isspace(*p1); p1++)
  187.                 if (! *p1) break;
  188.         }
  189.     }
  190.  
  191.     return (TCL_OK);
  192. }
  193.  
  194. static int
  195. widgetCmd(clientData, interp, argc, argv)
  196.     ClientData clientData;
  197.     Tcl_Interp *interp;
  198.     int argc;
  199.     char *argv[];
  200. {
  201.     return (_widgetCmd (clientData, interp, argc, argv, FALSE));
  202. }
  203.  
  204. static int
  205. resourceCmd(clientData, interp, argc, argv)
  206.     ClientData clientData;
  207.     Tcl_Interp *interp;
  208.     int argc;
  209.     char *argv[];
  210. {
  211.     /* for now, this does the same thing as widgetCommand */
  212.     return (_widgetCmd (clientData, interp, argc, argv, FALSE));
  213. }
  214.  
  215. static int
  216. rilParentCmd (clientData, interp, argc, argv)
  217.     ClientData clientData;
  218.     Tcl_Interp *interp;
  219.     int argc;
  220.     char *argv[];
  221. {
  222.     int i;
  223.  
  224.     if (!strcmp(argv[1], "push"))
  225.     {
  226.         DEBUG (fprintf (stderr, "RilParent push <%s>\n", argv[2]););
  227.         if (++rilParent >= MAX_PARENT_LEVEL)
  228.         {
  229.             fprintf (stderr, "RilParent: too many levels deep\n");
  230.             exit(-1);
  231.         }
  232.         rilParentStrings[rilParent] = (char*) XtMalloc(strlen(argv[2])+1);
  233.         strcpy (rilParentStrings[rilParent], argv[2]); 
  234.  
  235.         strcpy (rilParentVar, rilParentStrings[1]);
  236.         for (i=2; i <= rilParent; i++)
  237.             strcat(rilParentVar, rilParentStrings[i]);
  238.         Tcl_SetVar (interp, "rilParent", rilParentVar, NULL);
  239.     }
  240.     else if (!strcmp(argv[1], "pop"))
  241.     {
  242.         DEBUG (fprintf (stderr, "RilParent pop\n"););
  243.  
  244.         if (rilParent < 1)
  245.         {
  246.             fprintf (stderr, "RilParent: too many pops\n");
  247.             exit(-1);
  248.         }
  249.  
  250.         XtFree (rilParentStrings[rilParent--]);
  251.         strcpy (rilParentVar, rilParentStrings[1]);
  252.         for (i=2; i <= rilParent; i++)
  253.             strcat(rilParentVar, rilParentStrings[i]);
  254.         Tcl_SetVar (interp, "rilParent", rilParentVar, NULL);
  255.  
  256.     }
  257.     else
  258.     {
  259.         fprintf (stderr, "RilParent: push or pop required\n");
  260.         exit (-1);
  261.     }
  262.  
  263.     DEBUG (fprintf (stderr, "rilParentVar = <%s>\n", rilParentVar););
  264.  
  265.     return (TCL_OK);
  266. }
  267.  
  268. static int
  269. rilSourceCmd (clientData, interp, argc, argv)
  270.     ClientData clientData;
  271.     Tcl_Interp *interp;
  272.     int argc;
  273.     char *argv[];
  274. {
  275.     return (doLoadFile(interp, argv[1]));
  276. }
  277.  
  278.  
  279. static int     
  280. rilCreateCommands(interp)
  281.     Tcl_Interp *interp;
  282. {
  283.     Tcl_CreateCommand(interp, "Widget", widgetCmd, (ClientData) "Widget",
  284.                       (Tcl_CmdDeleteProc *) NULL);
  285.     Tcl_CreateCommand(interp, "Resources", resourceCmd, (ClientData) "Resources",
  286.                       (Tcl_CmdDeleteProc *) NULL);
  287.     Tcl_CreateCommand(interp, "RilParent", rilParentCmd, (ClientData) "RilParent",
  288.                       (Tcl_CmdDeleteProc *) NULL);
  289.     Tcl_CreateCommand(interp, "RilSource", rilSourceCmd, (ClientData) "RilSource",
  290.                       (Tcl_CmdDeleteProc *) NULL);
  291. }
  292.  
  293.  
  294.  
  295. int 
  296. rilLoadFile(dpy, filename, interp)
  297.     Display *dpy;
  298.     char *filename;
  299.     Tcl_Interp *interp;
  300. {
  301.     Boolean flag = FALSE;
  302.     char buf[10];
  303.  
  304.     if (!interp)
  305.     {
  306.         interp = Tcl_CreateInterp();        
  307.         flag = TRUE;
  308.     }
  309.  
  310.     rilCreateCommands(interp);
  311.  
  312.     sprintf (buf, "%d.%d", XProtocolVersion(dpy), XtSpecificationRelease);
  313.     Tcl_SetVar (interp, "rilXVersion", buf, NULL);
  314.  
  315.     Tcl_SetVar (interp, "rilProjectRoot", PROJECTROOT, NULL);
  316.  
  317.     doLoadFile(interp, filename);
  318.  
  319.     if (flag)
  320.         Tcl_DeleteInterp(interp);
  321. }
  322.  
  323.  
  324. static int
  325. doLoadFile(interp, filename)
  326.     Tcl_Interp *interp;
  327.     char *filename;
  328. {
  329.     int result;
  330.     char cmdbuf[256];
  331.  
  332.     /*
  333.      * look for .ril file in current dir, then in XAPPLRESDIR then in 
  334.      * default /usr/X11R5/lib/X11/app-defaults
  335.      */
  336.     sprintf (cmdbuf, "source \"%s\"", filename);
  337.     if ((result = rilEvalCommand(interp, cmdbuf)) == TCL_OK)
  338.     {
  339.         DEBUG (fprintf(stderr,"executed <%s> ok\n", cmdbuf););
  340.         return (result);
  341.     }
  342.  
  343.     Tcl_ResetResult(interp);
  344.     sprintf (cmdbuf, "source \"%s/%s\"",
  345.              getenv("XAPPLRESDIR"), filename);
  346.     if ((result = rilEvalCommand(interp, cmdbuf)) == TCL_OK)
  347.     {
  348.         DEBUG (fprintf(stderr,"executed <%s> ok\n", cmdbuf););
  349.         return (result);
  350.     }
  351.  
  352.     Tcl_ResetResult(interp);
  353.     sprintf (cmdbuf, "source \"%s/lib/X11/app-defaults/%s\"", 
  354.              PROJECTROOT, filename);
  355.     if ((result = rilEvalCommand(interp, cmdbuf)) == TCL_OK)
  356.     {
  357.         DEBUG (fprintf(stderr,"executed <%s> ok\n", cmdbuf););
  358.         return (result);
  359.     }
  360.  
  361.     Tcl_ResetResult(interp);
  362.     sprintf (cmdbuf, "source \"%s/lib/X11/app-defaults/%s/%s\"", 
  363.              PROJECTROOT, ProgramName, filename);
  364.     if ((result = rilEvalCommand(interp, cmdbuf)) == TCL_OK)
  365.     {
  366.         DEBUG (fprintf(stderr,"executed <%s> ok\n", cmdbuf););
  367.         return (result);
  368.     }
  369.  
  370.     fprintf (stderr, "Could not find ril file %s\n", filename);
  371.     exit(-1);
  372. }
  373.  
  374. static int rilEvalCommand (interp, cmd)
  375.     Tcl_Interp *interp;
  376.     char *cmd;
  377. {
  378.     errno = 0;
  379.     if (Tcl_Eval(interp, cmd, 0, 0) == TCL_OK)
  380.         return (TCL_OK);
  381.     else if (errno == ENOENT)
  382.         return (TCL_ERROR);
  383.     else
  384.     {
  385. #if 0
  386. /* nice if line number was correct */
  387.         fprintf (stderr, "Error <%s> command <%s> line %d\n",
  388.                  interp->result, cmd, interp->errorLine);
  389. #else
  390.         fprintf (stderr, "Error <%s> command <%s>\n", interp->result, cmd);
  391. #endif
  392.         exit(-1);
  393.     }
  394. }
  395.  
  396. int 
  397. rilCompile(filename)
  398.     char *filename;
  399. {
  400.     int i, result;
  401.     char cmdbuf[256];
  402.     Tcl_Interp *interp;
  403.  
  404.     /* -- Get ready TCL */
  405.     interp = Tcl_CreateInterp();
  406.     rilCreateCommands(interp);
  407.     
  408.     sprintf (cmdbuf, "source %s", filename);
  409.     if ((result = Tcl_Eval(interp, cmdbuf, 0, 0)) == TCL_OK)
  410.     {
  411.         printf ("\n!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  412.         printf ("! RESOURCE COMMAND\n");
  413.         printf ("!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  414.         for (i=0; i < resbufLen; i++)
  415.             printf ("%s\n", resbuf[i]);
  416.  
  417.  
  418.         printf ("\n!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  419.         printf ("! WIDGET COMMAND \n");
  420.         printf ("!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  421.         printf ("\n%s\n", widgetBuf);
  422.     }
  423.     fprintf (stderr, "%s\n", interp->result);
  424.     return (result);
  425. }
  426.  
  427.  
  428. int 
  429. rilGenerate (filename, str)
  430.     char *filename;
  431.     char **str;
  432. {
  433. #if 0
  434.     int result;
  435.     char cmdbuf[256];
  436.     Tcl_Interp *interp;
  437.  
  438.     /* -- Get ready TCL */
  439.     interp = Tcl_CreateInterp();
  440.     rilCreateCommands(interp);
  441.  
  442.     sprintf (cmdbuf, "source %s", filename);
  443.     result = Tcl_Eval(interp, cmdbuf, 0, 0);
  444.  
  445.     fprintf (stderr, "%s\n", interp->result);
  446.  
  447.     *str = resbuf;
  448.     return (result);
  449. #endif
  450. }
  451.  
  452. Widget 
  453. rilInterpInit(interp, app_context_return, application_class, options, num_options,
  454.     argc_in_out, argv_in_out, fallback_resources, 
  455.     args_in, num_args_in)
  456.     Tcl_Interp *interp;
  457.     XtAppContext * app_context_return;
  458.     String application_class;
  459.     XrmOptionDescRec *options;
  460.     Cardinal num_options, *argc_in_out, num_args_in;
  461.     String *argv_in_out, * fallback_resources;     
  462.     ArgList args_in;
  463. {
  464.     XtAppContext app_con;
  465.     Display * dpy;
  466.     String *saved_argv;
  467.     register int i, saved_argc = *argc_in_out;
  468.     Widget root;
  469.     Arg args[3], *merged_args;
  470.     Cardinal num = 0;
  471.  
  472.     char rilFileName[80];
  473.     XrmDatabase db;
  474.  
  475.     XtToolkitInitialize();
  476.     
  477. /*
  478.  * Save away argv and argc so we can set the properties later 
  479.  */
  480.     
  481.     saved_argv = (String *)
  482.         XtMalloc ( (Cardinal)((*argc_in_out + 1) * sizeof(String)) );
  483.  
  484.     for (i = 0 ; i < saved_argc ; i++)
  485.         saved_argv[i] = argv_in_out[i];
  486.     saved_argv[i] = NULL;    /* NULL terminate that sucker. */
  487.  
  488.     app_con = XtCreateApplicationContext();
  489.  
  490.  
  491.     dpy = XtOpenDisplay(app_con, (String) NULL, NULL, application_class,
  492.             options, num_options, argc_in_out, argv_in_out);
  493.  
  494.     if (dpy == NULL)
  495.     {
  496.         fprintf (stderr, "Can't Open display");
  497.         exit (-1);
  498.     }
  499.  
  500.     if ((ProgramName = (char*)strrchr(argv_in_out[0], '/')) != NULL)
  501.         ++ProgramName;
  502.     else
  503.         ProgramName = argv_in_out[0];
  504.  
  505.     sprintf (rilFileName, "%s.ril", application_class);
  506.     rilLoadFile (dpy, rilFileName, interp);
  507.  
  508.     if (resbufLen > 0)
  509.     {
  510.         resbuf[resbufLen] = NULL;
  511.         XtAppSetFallbackResources(app_con, resbuf);
  512.     }
  513.     else
  514.     {
  515.     }
  516.  
  517.     db = XrmGetStringDatabase(widgetBuf);
  518.     XrmMergeDatabases (db, &(dpy->db));
  519.     
  520.     XtSetArg(args[num], XtNscreen, DefaultScreenOfDisplay(dpy)); num++;
  521.     XtSetArg(args[num], XtNargc, saved_argc);                     num++;
  522.     XtSetArg(args[num], XtNargv, saved_argv);                     num++;
  523.     
  524.     merged_args = XtMergeArgLists(args_in, num_args_in, args, num);
  525.     num += num_args_in;
  526.     
  527.     root = XtAppCreateShell(NULL, application_class, 
  528.                             applicationShellWidgetClass,dpy, merged_args, num);
  529.     
  530.     if (app_context_return != NULL)
  531.         *app_context_return = app_con;
  532.     
  533.     XtFree((XtPointer)merged_args);
  534.     XtFree((XtPointer)saved_argv);
  535.     return(root);
  536. }
  537.  
  538. Widget 
  539. rilInitialize(app_context_return, application_class, options, num_options,
  540.     argc_in_out, argv_in_out, fallback_resources, 
  541.     args_in, num_args_in)
  542.     XtAppContext * app_context_return;
  543.     String application_class;
  544.     XrmOptionDescRec *options;
  545.     Cardinal num_options, *argc_in_out, num_args_in;
  546.     String *argv_in_out, * fallback_resources;     
  547.     ArgList args_in;
  548. {
  549.     return (rilInterpInit(NULL, app_context_return, application_class, 
  550.                           options, num_options,
  551.                           argc_in_out, argv_in_out, fallback_resources, 
  552.                           args_in, num_args_in));
  553. }
  554.  
  555.  
  556.  
  557.  
  558. /* A work in progress */
  559. char *rilResolvePathName(dpy)
  560.     Display *dpy;
  561. {
  562. #if 0
  563.     char* getenv();
  564.     char* filename;
  565.     char* path;
  566.     Boolean deallocate = False;
  567.     
  568.     if (!(path = getenv("XUSERFILESEARCHPATH")))
  569.     {
  570.         char *old_path;
  571.         char *homedir;
  572.         homedir = getenv("HOME");
  573.  
  574.         if (!(old_path = getenv("XAPPLRESDIR")))
  575.         {
  576.             char *path_default =
  577.         "%s/%%L/%%N%%C:%s/%%l/%%N%%C:%s/%%N%%C:%s/%%L/%%N:%s/%%l/%%N:%s/%%N";
  578.             path = XtMalloc((6*strlen(homedir) + strlen(path_default)));
  579.             sprintf(path, path_default,
  580.                     homedir, homedir, homedir, homedir, homedir, homedir );
  581.         }
  582.         else
  583.         {
  584.             char *path_default =
  585.         "%s/%%L/%%N%%C:%s/%%l/%%N%%C:%s/%%N%%C:%s/%%N%%C:%s/%%L/%%N:%s/%%l/%%N:%s/%%N:%s/%%N";
  586.             path = XtMalloc((6*strlen(old_path) + 2*strlen(homedir)
  587.                              + strlen(path_default)));
  588.             sprintf(path, path_default, old_path, old_path, old_path, homedir,
  589.                     old_path, old_path, old_path, homedir);
  590.         }
  591.         deallocate = True;
  592.     }
  593.     
  594.     filename = XtResolvePathname(dpy, NULL, NULL, NULL, path, NULL, 0, NULL);
  595.     
  596.     if (deallocate)
  597.         XtFree(path);
  598.     
  599.     return (filename);
  600. #endif
  601. }
  602.